只有当包展开发生或参数列表的末尾时，包展开的模板参数推导才有效。从列表中提取第一个元素相当简单:

\begin{lstlisting}[style=styleCXX]
template<typename... Types>
struct Front;

template<typename FrontT, typename... Types>
struct Front<FrontT, Types...> {
	using Type = FrontT;
};
\end{lstlisting}

在第16.4节中描述的对偏特化的限制，不能简单地提取列表的最后一个元素:

\begin{lstlisting}[style=styleCXX]
template<typename... Types>
struct Back;

template<typename BackT, typename... Types>
struct Back<Types..., BackT> { // ERROR: pack expansion not at the end of
	using Type = BackT; // template argument list
};
\end{lstlisting}

可变参数函数模板的模板参数推导也受到类似的限制。关于包展开和偏特化的模板参数推导的规则将放宽，允许包展开发生在模板参数列表的任何地方，这使得操作更加简单。此外，推论允许在同一个参数列表中进行多个包扩展(尽管可能性较小):

\begin{lstlisting}[style=styleCXX]
template<typename... Types> class Tuple {
};

template<typename T, typename... Types>
struct Split;

template<typename T, typename... Before, typename... After>
struct Split<T, Before..., T, After...> {
	using before = Tuple<Before...>;
	using after = Tuple<After...>;
};
\end{lstlisting}

允许多个包扩展会带来额外的复杂性。例如，Split是在T第一次出现时分开，在T最后一次出现时分开，还是在两者之间分开?推导过程的复杂性达到多少时，编译器才会放弃推导?













































